package io.gitee.cdw.sensitive.serializer;

import io.gitee.cdw.sensitive.model.SensitiveConst;
import io.gitee.cdw.sensitive.model.SensitiveSerializerConfig;
import io.gitee.cdw.sensitive.model.StrategyConfig;
import io.gitee.cdw.sensitive.strategy.IStrategy;
import io.gitee.cdw.sensitive.strategy.StrategyManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * 数据脱敏序列化类
 *
 * @author Created by chendw on 2023/5/10 17:28.
 */
@Component
@Slf4j
public class SensitiveSerializer {

    @Resource
    protected StrategyManager strategyManager;

    public Object serialize(String field, Object value) {
        if (strategyManager.contains(field)) {
            SensitiveSerializerConfig sensitiveSerializerConfig = strategyManager.getSensitiveSerializerConfig(field);
            log.debug("sensitive field: {} {}", field, sensitiveSerializerConfig);

            IStrategy strategy = sensitiveSerializerConfig.getStrategy();

            StrategyConfig strategyConfig = sensitiveSerializerConfig.getConfig();
            String pattern = strategyConfig.getPattern();
            int left = strategyConfig.getLeft();
            int right = strategyConfig.getRight();
            String apiName = strategyConfig.getName();

            // 通过RequestContextHolder获取Http请求的接口名称
            String reqName = getReqNameFromRequest();

            boolean contains = (StringUtils.isNotBlank(apiName) && apiName.equals(reqName))
                    || StringUtils.isBlank(apiName);

            // 判断HttpHeader是否存在敏感请求标志
            if (contains) {
                if (StringUtils.isNotBlank(pattern)) {
                    // 如果正则不为空则使用正则脱敏
                    return strategy.desensitizationByPattern((String) value, pattern, SensitiveConst.SENSITIVE_MASK_CHAR);
                } else {
                    // 采用指定的脱敏策略
                    return strategy.desensitization((String) value, left, right);
                }
            }
        }
        return value;
    }

    /**
     * 获取当前请求的接口名称
     *
     * @return 接口名称
     */
    private String getReqNameFromRequest() {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String reqName = null;
        if (servletRequestAttributes != null) {
            HttpServletRequest request = servletRequestAttributes.getRequest();
            // 可以通过自定义header指定接口名称
            reqName = (String) request.getAttribute(SensitiveConst.SENSITIVE_KEY);

            // 如果未指定自定义的接口名称，默认使用接口名称
            if (StringUtils.isBlank(reqName)) {
                reqName = request.getRequestURI();
            }
        }
        return reqName;
    }

}
